-
Notifications
You must be signed in to change notification settings - Fork 151
bugfix: Fix inconsistent mine collision behaviour #2208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
bugfix: Fix inconsistent mine collision behaviour #2208
Conversation
Greptile Overview
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Include/Common/GameDefines.h | Added RETAIL_COMPATIBLE_CIRCLE_FILL_ALGORITHM preprocessor define to control circle fill algorithm selection |
| Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp | Implemented precise circle fill algorithm using circle-to-AABB collision test and added conditional compilation to preserve retail behavior |
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp | Implemented precise circle fill algorithm using circle-to-AABB collision test and added conditional compilation to preserve retail behavior (Zero Hour version) |
Sequence Diagram
sequenceDiagram
participant PD as PartitionData
participant PM as PartitionManager
participant Cell as PartitionCell
Note over PD: updateCellsTouched() called
alt Geometry is SPHERE or CYLINDER
alt RETAIL_COMPATIBLE_CIRCLE_FILL_ALGORITHM = 1
PD->>PD: doCircleFill(x, y, radius)
Note over PD: Uses midpoint circle algorithm<br/>(less accurate)
else RETAIL_COMPATIBLE_CIRCLE_FILL_ALGORITHM = 0
PD->>PD: doCircleFillPrecise(x, y, radius)
Note over PD: Calculate bounding cells
PD->>PM: worldToCell(centerX ± radius, centerY ± radius)
PM-->>PD: minCellX, minCellY, maxCellX, maxCellY
PD->>PM: getCellSize()
PM-->>PD: cellSize
loop For each cell (x, y) in bounding box
PD->>PD: doesCircleOverlapCell(centerX, centerY, radius, cellX, cellY, cellSize)
Note over PD: Find closest point on cell to circle<br/>Check if distance < radius
alt Circle overlaps cell
PD->>PM: getCellAt(x, y)
PM-->>PD: cell
alt cell exists
PD->>Cell: addSubPixToCoverage(cell)
end
end
end
end
end
Note over PD: Partition cells now accurately<br/>reflect object's collision bounds
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 files reviewed, 2 comments
| // TheSuperHackers @bugfix Stubbjax 29/01/2026 Use precise circle fill to improve | ||
| // collision accuracy, most notably for objects with geometry radii >= 20 and < 40. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
date in comment shows 29/01/2026 but PR was created on 2026-01-28
Prompt To Fix With AI
This is a comment left during a code review.
Path: Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp
Line: 2122:2123
Comment:
date in comment shows 29/01/2026 but PR was created on 2026-01-28
How can I resolve this? If you propose a fix, please make it concise.| // TheSuperHackers @bugfix Stubbjax 29/01/2026 Use precise circle fill to improve | ||
| // collision accuracy, most notably for objects with geometry radii >= 20 and < 40. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
date in comment shows 29/01/2026 but PR was created on 2026-01-28
Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp
Line: 2126:2127
Comment:
date in comment shows 29/01/2026 but PR was created on 2026-01-28
How can I resolve this? If you propose a fix, please make it concise.
Fixes #24 from the patch repository
This change fixes inconsistent mine collision detection by replacing the partition manager's circle fill algorithm with a more precise algorithm. The new logic is placed behind a new
RETAIL_COMPATIBLE_CIRCLE_FILL_ALGORITHMpreprocessor directive to help isolate the change as it is potentially slightly less performant.The retail circle fill logic - an implementation of the midpoint circle algorithm - does not accurately cover the cells occupied by spherical or cylindrical geometry. This leads to various collision inaccuracies throughout the game, one of which is the infamous mine behaviour described in #24. Various collision logic is only processed within partition cells that are considered occupied - the partition cells act as a 'broad phase' to determine which geometry then needs to be checked for overlaps.
It's particularly important to note that objects with a geometry radius >= 20 and < 40 (the most common range) only cover a single partition cell, for example Tunnel Networks (radius: 25) and Stinger Sites (radius: 30). This can be seen in the video below. A blue/green square indicates an occupied cell.
SINGLE_CELL.mp4
Mines happen to fit right within this range with a radius of 30, and therefore only end up covering a single cell. This is a problem as most units happen to be smaller than a single partition cell, and can end up bypassing adjacent occupied cells altogether. Below is an example of this happening.
DODGER.mp4
Below is a demonstration of the difference in cell coverage in retail (left, blue) vs this change (right, yellow) at different radii. It should be apparent that retail cell coverage becomes more inaccurate as geometry radii increases towards each multiple of the partition cell size (40, 80, 120, etc.), whereas the new algorithm is always perfectly accurate. Note that radii < 20 uses a separate dedicated 'small geometry' algorithm which is 100% accurate.
GRID_COMP.mp4
And below is a direct comparison between retail mine cell coverage and the new mine cell coverage.
Before
Mine cell coverage using the retail algorithm
After
Mine cell coverage using the new algorithm
And some real gameplay demonstrations for good measure.
Before
The Technical skips over several mines, allowing the terrorists to destroy the War Factory
BAD_MINES.mp4
After
The Technical and terrorists explode on the mines as expected
GOOD_MINES.mp4